package nl.twingate.views;


import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import org.apache.http.util.ByteArrayBuffer;
import nl.twingate.R;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.Toast;

/**
 * This activity shows a nice loading screen,downloads updates and installs them (user action required)
 * @author Marijn Oosterveld
 *
 */
public class Main extends Activity {
	
	//Some private stuff ;)
	private BroadcastReceiver backendMessageHandler;
	private String tag = "Welcome";
	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        
        //Start our updater
        new softwareUpdateTask(this).execute();
    }

    /**
     * Actions todo when this activity gets destroyed
     */
    @Override
    protected void onDestroy() {
    	super.onDestroy();
    	
    	//unregister our NotifyUser
    	unregisterReceiver(backendMessageHandler);
    	
    }    

    
    /**
	 * This task downloads new software updates, and shows the user its progress.
	 * All this is put in this AsyncTask to "de-stress" the GUI thread
	 * @author Marijn Oosterveld
	 */
	private class softwareUpdateTask extends AsyncTask<Void, String, Void> { 

		ProgressBar prgBar;
		Context c;
		
		/**
		 * Default constructor
		 * @param c
		 */
		public softwareUpdateTask(Context c){
			//Reference back to the view
			this.c = c;
		}
		
		/**
		 * Given an URL, download to the SDCARD/download/pending.apk and install
		 * returns true if the download succeeded, and false if not
		 * @param URL
		 */
		private boolean DownloadFromUrl(String URL) {
	        try {
	                URL url = new URL(URL);
	              //Create local emprty file to save the apk file to
	              String PATH = Environment.getExternalStorageDirectory() + "/download/";
	              File filepath = new File(PATH);
	              filepath.mkdirs();
	                File file = new File(filepath, "pending.apk");

	                long startTime = System.currentTimeMillis();
	                Log.d(tag, "download begining");
	                Log.d(tag, "download url:" + url);
	                //Log.d("ImageManager", "downloaded file name:" + p);
	                /* Open a connection to that URL. */
	                URLConnection ucon = url.openConnection();

	                /*
	                 * Define InputStreams to read from the URLConnection.
	                 */
	                InputStream is = ucon.getInputStream();
	                BufferedInputStream bis = new BufferedInputStream(is);

	                /*
	                 * Read bytes to the Buffer until there is nothing more to read(-1).
	                 */
	                ByteArrayBuffer baf = new ByteArrayBuffer(50);
	                int current = 0;
	                while ((current = bis.read()) != -1) {
	                        baf.append((byte) current);
	                }

	                /* Convert the Bytes read to a String. */
	                FileOutputStream fos = new FileOutputStream(file);
	                fos.write(baf.toByteArray());
	                fos.close();
	                Log.d(tag, "download ready in"
	                                + ((System.currentTimeMillis() - startTime) / 1000)
	                                + " sec");

	        } catch (Exception e) {
	                Log.e(tag, "Error: " + e);
	                return false;
	        }
	        
	        return true;

	    }
		
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			
			//Load our progressbar
			prgBar = (ProgressBar) findViewById(R.id.splashProgress);
			prgBar.setProgress(10);
		}
		
		
		@Override
		protected Void doInBackground(Void... params) {
			
			//Set the Thread name, usefull for debugging
			Thread.currentThread().setName("SoftwareUpdateTask");
			
			// Load our download URLs from our resource file
        	Resources res = c.getResources();
			String[] URLs = res.getString(R.string.DownloadURLS).split(";");
			
			//Notify the user that we loaded the links
			publishProgress(new String[] {"" + 20, "Loaded " + URLs.length + " software packages"});//20%
			
			
			// Loadchunks ; the percentage that the bar goes up per download
			int percentagePerDownload = 80 / URLs.length;
			int currentpercentage = 0;
			
			//Now go through all the URLS and update them!
			for(String currentURL : URLs){		
				
				publishProgress(new String[] { "" + currentpercentage, "Currently downloading: " + currentURL});
				
				boolean downloadsuccess = DownloadFromUrl(currentURL);
				if(downloadsuccess != true){
					publishProgress(new String[] { "" + currentpercentage, "FAILED: " + currentURL});
				}

		        Log.i(tag, "Launching installer");
		        //Now launch the installer for this APK
		        Intent intent = new Intent(Intent.ACTION_VIEW);
		        intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + "pending.apk")), "application/vnd.android.package-archive");
		        startActivity(intent); 
		        
		        if(currentpercentage < 100){
		        	currentpercentage = (currentpercentage + percentagePerDownload);
		        }
		        
		        publishProgress(new String[] { "" + currentpercentage, "Done: " + currentURL});
			}
			
			return null;
			
			
		}
		
		@Override
		protected void onProgressUpdate(String... values) {
			super.onProgressUpdate(values);
			prgBar.setProgress(Integer.parseInt(values[0]));
			
			//Show a message to the GUI if the message isn't empty
			if(!values[1].equals("")){
				Toast.makeText(Main.this, values[1], Toast.LENGTH_LONG * 4).show();
			}
		}
		
		@Override
		protected void onPostExecute(Void result) {
			super.onPostExecute(result);
			
			try {
				this.finalize();
				super.finalize();
			} catch (Throwable e) {
				e.printStackTrace();
			}
			
		}
		
	
	}

}